<template>
  <el-popover
    v-model:visible="visible"
    placement="right"
    open-delay="400"
    close-delay="300"
    width="auto"
    :trigger="triggerType"
    :disabled="popoverDisabled"
  >
    <MaterialVideo
      v-if="type == MATERIAL_TYPE.video"
      :outSidePicture="outSidePicture"
      :url="url"
      :visible="visible"
    />
    <MaterialImage
      v-if="type == MATERIAL_TYPE.image"
      :url="Array.isArray(url) ? url[0] : url"
      :previewList="Array.isArray(url) && url.length > 0 ? url : previewList"
      :visible="visible"
    />
    <MaterialAudio
      v-if="type == MATERIAL_TYPE.audio"
      :url="url"
      :name="name"
      :visible="visible"
    />
    <template #reference>
        <div :class="['content', { full: sizeAuto }]">
          <div class="content-container" @click="imageClick">
            <img class="effect" :src="outSidePicture || initOutSidePicture" />
            <!-- 视频媒体 -->
            <template v-if="type == MATERIAL_TYPE.video">
              <video
                v-if="pictureInPicture && !outSidePicture"
                ref="video"
                preload="metadata"
                :src="url"
                :muted="muted"
                :poster="cover || undefined"
              />
              <img
                v-else-if="outSidePicture"
                :class="['cover', coverClass]"
                :src="outSidePicture"
              />
              <el-icon class="icon">
                <IEpVideoPlay />
              </el-icon>
            </template>
            <!-- 图片媒体 -->
            <template v-else-if="type == MATERIAL_TYPE.image">
              <img v-if="outSidePicture" class="image" :src="outSidePicture" />
              <div v-else class="empty-placeholder">
                <el-icon class="empty-icon">
                  <IEpPicture />
                </el-icon>
                <span class="empty-text">暂无图片</span>
              </div>
            </template>
            <!-- 音频媒体 -->
            <template v-else-if="type == MATERIAL_TYPE.audio">
              <div class="audio-placeholder">
                <el-icon class="audio-icon">
                  <IEpHeadset />
                </el-icon>
                <span class="audio-text">{{ name || '音频文件' }}</span>
              </div>
            </template>
          </div>
          <ImageBadge v-if="hasPreviewList && imageBadge" :count="previewList.length" />
          <div v-if="actions" class="actions">
            <span class="action-icon preview" @click="actionPreview">
              <el-icon><ZoomIn /></el-icon>
            </span>
            <span class="action-icon delete" @click="actionDelete">
              <el-icon><Delete /></el-icon>
            </span>
          </div>
        </div>
    </template>
  </el-popover>
</template>

<script setup>
import MaterialVideo from "./components/Video.vue";
import MaterialImage from "./components/Image.vue";
import MaterialAudio from "./components/Audio.vue";
import ImageBadge from "./components/ImageBadge.vue";
import { Delete, ZoomIn } from "@element-plus/icons-vue";

const MATERIAL_TYPE = {
  image: "image",
  video: "video",
  audio: "audio",
};

const props = defineProps({
  /** @name 媒体类型，参考market子项目的MATERIAL_TYPE常量 **/
  type: {
    type: [String],
    default: "video", // 默认为视频
  },
  /** @name 媒体地址，兼容图片多图情况 **/
  url: {
    type: [String, Array],
    default: "",
  },
  /** @name 媒体封面地址-仅用于视频 **/
  cover: {
    type: String,
    default: "",
  },
  /** @name 媒体名称-仅用于音频 **/
  name: {
    type: String,
    default: "",
  },
  /** @name el-popover打开的方式 **/
  triggerType: {
    type: String,
    default: "click",
  },
  /** @name 是否显示画中画 **/
  pictureInPicture: {
    type: Boolean,
    default: true,
  },
  /** @name 是否静音-仅用于视频 **/
  muted: {
    type: Boolean,
    default: false,
  },
  /** @name 封面的class-仅用于视频 **/
  coverClass: {
    type: String,
    default: "",
  },
  /** @name 多图是否显示图片数量-结合previewList **/
  imageBadge: {
    type: Boolean,
    default: true,
  },
  /** @name 是否禁用预览功能 **/
  disabledPreview: {
    type: Boolean,
    default: false,
  },
  /** @name 是否开启轮播预览功能 **/
  previewList: {
    type: Array,
    default: () => [],
  },
  /** @name 是否显示操作按钮 **/
  actions: {
    type: Boolean,
    default: false,
  },
  /** @name 组件尺寸是否固定 **/
  sizeAuto: false,
});
const emits = defineEmits(["actionPreview", "actionDelete", "imageClick"]);

const visible = ref(false);
const hasPreviewList = computed(() => {
  // 如果有传入previewList，则使用previewList的长度
  if (props?.previewList?.length) {
    return true;
  }
  // 如果url是数组且type是image，则认为有预览列表
  if (props.type === MATERIAL_TYPE.image && Array.isArray(props.url) && props.url.length > 0) {
    return true;
  }
  return false;
});
const popoverDisabled = computed(() => {
  if (props.disabledPreview) {
    return true;
  }
  if (props.type === MATERIAL_TYPE.image) {
    if (!hasPreviewList.value) {
      return true;
    }
  }
  if (props.type === MATERIAL_TYPE.audio) {
    // 音频类型不禁用预览，允许弹出播放器
    return false;
  }
  return false;
});

const initOutSidePicture =
  "https://weflycdn.52tt.com/ad/mp4/164845300946112600.mp4?vframe/jpg/offset/1/";

/** @name 用于制作毛玻璃的效果或者获取媒体的尺寸信息 **/
const outSidePicture = computed(() => {
  if (props.type === MATERIAL_TYPE.video) {
    return props.cover;
  }
  if (props.type === MATERIAL_TYPE.image) {
    // 如果url是数组，取第一个元素作为封面
    if (Array.isArray(props.url) && props.url.length > 0) {
      return props.url[0];
    }
    // 如果url是字符串
    if (props.url && typeof props.url === 'string') {
      return props.url;
    }
    // 如果有previewList，取第一个
    if (hasPreviewList.value && props.previewList.length > 0) {
      return props.previewList[0];
    }
  }
  if (props.type === MATERIAL_TYPE.audio) {
    // 音频类型不需要封面图片
    return "";
  }
  return "";
});

/** @name 预览 **/
function actionPreview() {
  emits("actionPreview", props.url);
}
/** @name 删除 **/
function actionDelete() {
  emits("actionDelete", props.url);
}
/** @name 图片点击 **/
function imageClick() {
  props.type === "image" && emits("imageClick", props.url);
}
</script>

<style lang="scss" scoped>
.content {
  width: 110px;
  height: 60px;
  cursor: pointer;
  text-align: center;
  position: relative;
  background-color: #232327;
  background-size: 70px auto;
  background-position: center;
  background-repeat: no-repeat;
  &.full {
    width: 100%;
    height: 100%;
  }
  .content-container {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow: hidden;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .effect {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    filter: blur(14px);
    opacity: 0.8;
  }
  .icon {
    z-index: 2;
    font-size: 24px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
  .cover,
  video,
  .image {
    position: relative;
    z-index: 1;
    max-width: 100%;
    max-height: 100%;
    object-fit: cover;
  }
  .empty-placeholder {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: #909399;
    
    .empty-icon {
      font-size: 30px;
      margin-bottom: 8px;
    }
    
    .empty-text {
      font-size: 14px;
      opacity: 0.8;
    }
  }
  
  .audio-placeholder {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: #c7c7c7;
    
    .audio-icon {
      font-size: 30px;
      margin-bottom: 8px;
    }
    
    .audio-text {
      font-size: 12px;
      opacity: 0.9;
      text-align: center;
      max-width: 90%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}
.actions {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  background-color: rgba(0, 0, 0, 0.5);
  cursor: default;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
  opacity: 0;
  font-size: 20px;
  transition: opacity 0.28s;
  .action-icon {
    font-size: 18px;
    color: #fff;
    margin: 0 5px;
    cursor: pointer;
    &:hover {
      color: #409eff;
    }
    &.delete:hover {
      color: #f56c6c;
    }
  }
}
.content:hover {
  .actions {
    opacity: 1;
  }
}
</style>
